In [240]:
%pylab
import pandas as pd
from pandas import Series, DataFrame
In [241]:
# Series 由一組 索引標籤+數據 組成
s = Series([4, 7, -5, 3])
s
Out[241]:
Series物件有 index 和 values屬性
In [242]:
# series的 index
# dtype是 int64
s.index
Out[242]:
In [243]:
# series的 value
s.values
Out[243]:
index如同Excel的 row number,但不一定是數字
和Excel最大的不同: Series 的 Index 可以有重複的值
In [244]:
s.index = pd.Index([0, 'a', 'a', 2])
s
Out[244]:
In [245]:
# 一個index可以對應多個rows
s['a']
Out[245]:
建構 Series物件的方式,索引不一定是數字
In [246]:
# 指定索引
s = Series([4, 7, -5, 3], index = ['d', 'b', 'a', 'c'])
s
Out[246]:
Series的index是一個 Index物件
In [247]:
# dtype是 object
s.index
Out[247]:
In [248]:
# 用索引取值
s['b']
Out[248]:
In [249]:
# 可以取多個值
s[['b', 'c']]
Out[249]:
In [250]:
# 各種運算之後,還是會保留index
# 可以使用 陣列式索引
s[s > 3]
Out[250]:
In [251]:
# 廣播運算
s * 2
Out[251]:
In [252]:
# 用 NumPy的頂級函示對Series做廣播運算
np.exp(s)
Out[252]:
In [253]:
# 可以將Series看成是一個有序字典
'b' in s
# 等同是 'b' in s.index
Out[253]:
In [254]:
'e' in s
Out[254]:
In [255]:
# 可以命名 Series物件
s.name = 'test'
s.name
Out[255]:
In [256]:
# 可以用Python字典來創建 Series
dt = {'Ohio' : 35000, 'Texas' : 71000, 'Oregon' : 16000, 'Utah' : 5000}
dt
Out[256]:
In [257]:
s1 = Series(dt)
s1
# Series等同是一個有序的字典
Out[257]:
In [258]:
s1.index
Out[258]:
In [259]:
# 建構Series的時候指定 index
# 其中 index California 在 dt中找不到,因此對應的value就標示為 NaN
states = ['Utah', 'California', 'Ohio', 'Oregon', 'Texas']
s2 = Series(dt, index = states)
s2
Out[259]:
In [260]:
# isnull, notnull 可用來檢測 NaN
pd.isnull(s2)
Out[260]:
In [261]:
pd.notnull(s2)
Out[261]:
In [262]:
# Series 的 isnull(), notnull()
s2.isnull()
Out[262]:
In [263]:
s2.notnull()
Out[263]:
In [264]:
s1
Out[264]:
In [265]:
s2
Out[265]:
In [266]:
s1 + s2
Out[266]:
In [267]:
s1 * s2
Out[267]:
In [268]:
# index可以隨時修改,會依照順序對應來修改
s2.index = ['Utah', 'New York', 'Ohio', 'Oregon', 'Texas']
s2
Out[268]:
In [269]:
# 由等長的列表或字典 建構 DataFrame
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = DataFrame(data)
frame
Out[269]:
In [270]:
# 可以指定columns的排序
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = DataFrame(data, columns = ['state', 'year', 'pop'])
frame
Out[270]:
In [271]:
# 找不到的column以NaN表示
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = DataFrame(data,
columns = ['state', 'year', 'pop', 'debt'],
index = ['one', 'two', 'three', 'four', 'five']
)
frame
Out[271]:
In [272]:
# DataFrame的 columns 索引,也是一個 Index物件
frame.columns
Out[272]:
In [273]:
# 將DataFrame的一個column取出成為一個Series
s = frame['state']
s
Out[273]:
In [274]:
# s 有 name屬性
s.name
Out[274]:
In [275]:
# 和 frame.state是一樣的,是一個Series
frame.state
Out[275]:
In [276]:
frame.year
Out[276]:
In [277]:
# row 也可以透過索引取得,返回的是一個視圖,和原本的物件共用資料
frame.state.two
Out[277]:
In [278]:
frame['state'].two
Out[278]:
In [279]:
frame.state['two']
Out[279]:
In [280]:
frame['state']['two']
Out[280]:
In [281]:
# 對整個Series賦值
frame.debt = 16.5
frame
Out[281]:
In [282]:
# 長度相同的情況下,會做 mapping
frame.debt = np.arange(5.)
frame
Out[282]:
In [283]:
# 使用Series並指定index,並將之填入一個DataFrame, 則DataFrame中空缺的位置都會被填上NaN
s = Series([-1.2, -1.5, -1.7], index = ['two', 'four', 'five'])
frame.debt = s
frame
Out[283]:
In [284]:
# 為不存在的column賦值會產生一個新的column
frame['eastern'] = (frame.state == 'Ohio')
frame
Out[284]:
In [285]:
frame['eastern']
Out[285]:
In [286]:
frame['eastern'].name
Out[286]:
In [287]:
# 以嵌套的字典建立DataFrame,外層的字典作為columns,內層的字典作為rows
pop = {'Nevada': {2001: 2.4, 2002: 2.9},
'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
pop
Out[287]:
In [288]:
frame = DataFrame(pop)
frame
Out[288]:
In [289]:
# 也可以進行轉置
frame.T
Out[289]:
In [290]:
# 內層的鍵會被合併、排序,但如果顯示地指定了索引,則不會合併或排序
DataFrame(pop, index = [2001, 2002, 2003])
Out[290]:
In [291]:
# 可以設置 rows, columns 的名稱
frame.index.name = 'year'
frame.columns.name = 'state'
frame
Out[291]:
In [292]:
# DataFrame 的 values屬性 返回一個二維 np.ndarray
v = frame.values
v
Out[292]:
In [293]:
obj = Series(range(3), name = 'd', index = ['a', 'b', 'c'])
obj
Out[293]:
In [294]:
index = obj.index
index # 是一個 Index物件
Out[294]:
In [295]:
index[1:]
Out[295]:
In [296]:
# Index物件是 immutable,不可以修改
# index[1] = 'b' # 會出錯
In [297]:
# 建立一個Index物件
index = pd.Index(np.arange(3))
index
Out[297]:
In [298]:
# 置換 Series物件的 index
obj.index = index
obj
Out[298]:
In [299]:
# 用Index物件來指定Series的index
obj2 = Series([1.5, -2.5, 0], index = index)
obj2
Out[299]:
In [300]:
obj2.index is index
Out[300]:
In [301]:
# Index 就像一個大小固定的 Set
frame
Out[301]:
In [302]:
'Nevada' in frame.columns
Out[302]:
In [303]:
2002 in frame.index
Out[303]:
In [304]:
obj = Series([4.5, 7.2, -5.3, 3.6], index = ['d', 'b', 'a', 'c'])
obj
Out[304]:
In [305]:
# reindex方法會根據新索引重新排序資料
obj.reindex(['a', 'b', 'c', 'd', 'e'])
Out[305]:
In [306]:
# 可以指定 空缺資料的填充值 fill_value
obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value = 0)
Out[306]:
In [307]:
obj = Series(['blue', 'purple', 'yellow'], index = [0, 2, 4])
obj
Out[307]:
In [308]:
# method參數可以以 "method" 指定 插值 的函式
obj.reindex(range(6), method = 'ffill')
Out[308]:
In [309]:
# 如果只傳入一個序列,則 .reindex()會優先對 row重新索引
frame = DataFrame(np.arange(9).reshape((3, 3)),
index = ['a', 'c', 'd'],
columns = ['Ohio', 'Texas', 'California'])
frame
Out[309]:
In [310]:
frame.reindex(['a', 'b', 'c', 'd'])
Out[310]:
In [311]:
# 可以以 columns參數重新索引columns
frame.reindex(columns = ['Texas', 'Ohio', 'California'])
Out[311]:
In [312]:
# 可以以 對 rows, columns都重新索引
frame.reindex(index = ['a', 'b', 'c', 'd'],
columns = ['Texas', 'Ohio', 'California'])
Out[312]:
In [313]:
# 插值
frame.reindex(index = ['a', 'b', 'c', 'd'],
columns = ['Texas', 'Ohio', 'California'],
method = 'ffill')
Out[313]:
In [314]:
# 用 ix函式來重新索引
frame.ix[['a', 'b', 'c', 'd'],
['Texas', 'Ohio', 'California']]
Out[314]:
In [315]:
# 以一個索引數組指定要刪除的元素
obj = Series(np.arange(5.), index = ['a', 'b', 'c', 'd', 'e'])
obj
Out[315]:
In [316]:
new_obj = obj.drop(['c'])
new_obj
Out[316]:
In [317]:
new_obj = obj.drop(['c', 'd'])
new_obj
Out[317]:
In [318]:
# 對於 DataFrame,可以刪除任意軸上的索引值
data = DataFrame(np.arange(16).reshape((4, 4)),
index = ['Ohio', 'Colorado', 'Utah', 'New York'],
columns = ['one', 'two', 'three', 'four'])
data
Out[318]:
In [319]:
# 對於 DataFrame,可以刪除任意軸上的索引值
data.drop(['Colorado', 'Ohio'])
Out[319]:
In [320]:
# axis = 0 或省略,可以刪除rows
data.drop(['Colorado', 'Ohio'])
Out[320]:
In [321]:
# axis = 1,可以刪除columns
data.drop(['two', 'four'], axis = 1)
Out[321]:
In [322]:
# Series的索引值不只是整數
obj = Series(np.arange(4.), index = ['a', 'b', 'c', 'd'])
obj
Out[322]:
In [323]:
# 單一值,不顯示索引
obj['b']
Out[323]:
In [324]:
# 單一值,不顯示索引
obj[1]
Out[324]:
In [325]:
# 多個值,顯示索引
obj[2:4]
Out[325]:
In [326]:
# 多個值,顯示索引,依照指定的順序
obj[['b', 'a', 'd']]
Out[326]:
In [327]:
# 多個值,顯示索引,依照指定的順序
obj[[1, 2, 3]]
Out[327]:
In [328]:
# 多個值,顯示索引
obj[obj < 2]
Out[328]:
In [329]:
# Series, DataFrame的切片算,其末端是包含的
obj['b':'d']
Out[329]:
In [330]:
# 賦值的方式也很簡單
obj['b':'c'] = 5
obj
Out[330]:
In [331]:
# 對於 DataFrame 索引,其實就是獲取一個或多個列
data = DataFrame(np.arange(16).reshape((4, 4)),
index = ['Ohio', 'Colorado', 'Utah', 'New York'],
columns = ['one', 'two', 'three', 'four'])
data
Out[331]:
In [332]:
data[['two', 'four']]
Out[332]:
In [333]:
data[['four', 'two']]
Out[333]:
In [334]:
data[[1, 3]]
Out[334]:
In [335]:
# 這是row方向的切片
data[:2]
Out[335]:
In [336]:
# 多層次的索引
data[data['three'] > 5]
Out[336]:
In [337]:
# 透過 boolean型態的 DataFrame 進行索引
data
Out[337]:
In [338]:
# 透過 boolean型態的 DataFrame 進行索引
data < 5
Out[338]:
In [339]:
data[data < 5]
Out[339]:
In [340]:
# ix 是重新索引的簡單方法
data.ix['Colorado', ['two', 'four']]
Out[340]:
In [341]:
# ix 對兩軸重新索引,依照指定的順序
data.ix[['Colorado', 'Utah'], [3, 0, 1]]
Out[341]:
In [342]:
# ix 索引,取出第0軸的第2個Series
data.ix[2]
Out[342]:
In [343]:
data.ix[: 'Utah', 'two']
Out[343]:
In [344]:
data.three > 5
Out[344]:
In [345]:
# 對兩個軸索引,取出交集
data.ix[data.three > 5, :3]
Out[345]:
pandas最重要的一個功能是: 可以對不同所引的對象進行算術運算。
在將對象相加時,若存在不同的索引,則結果的索引就是該索引對的聯集。
In [346]:
s1 = Series([7.3, -2.5, 3.4, 1.5], index = ['a', 'c', 'd', 'e'])
s2 = Series([-2.1, 3.6, -1.5, 4, 3.1], index = ['a', 'c', 'e', 'f', 'g'])
In [347]:
s1
Out[347]:
In [348]:
s2
Out[348]:
In [349]:
# 兩個Series的索引會自動對齊,空缺的值填入NaN
s1 + s2
Out[349]:
In [350]:
# 對於 DataFrame,索引自動對齊會發生在row 和 column方向
df1 = DataFrame(np.arange(9.).reshape((3, 3)),
index = ['Ohio', 'Texas', 'Colorado'],
columns = list('bcd'))
df2 = DataFrame(np.arange(12.).reshape((4, 3)),
index = ['Utah', 'Ohio', 'Texas', 'Oregon'],
columns = list('bde'))
In [351]:
df1
Out[351]:
In [352]:
df2
Out[352]:
In [353]:
df1 + df2
Out[353]:
In [354]:
df1 = DataFrame(np.arange(12.).reshape((3, 4)),
columns = list('abcd'))
df2 = DataFrame(np.arange(20.).reshape((4, 5)),
columns = list('abcde'))
In [355]:
df1
Out[355]:
In [356]:
df2
Out[356]:
In [357]:
# 以指定的預設值取代 NaN作為自動填充值
# 但是兩個DataFrame都沒有的元素位置,還是會被填入NaN
df1.add(df2, fill_value = 0)
Out[357]:
In [358]:
# 重新索引的時候,也可以指定填充值
df1.reindex(columns = df2.columns, fill_value = 0)
Out[358]:
In [359]:
arr = np.arange(12.).reshape((3, 4))
In [360]:
arr
Out[360]:
In [361]:
arr[0]
Out[361]:
In [362]:
# 算術運算 會進行 廣播
arr - arr[0]
Out[362]:
In [363]:
# DataFrame 和 Series 之間也是如此
df = DataFrame(np.arange(12.).reshape((4, 3)),
columns = list("bde"),
index = ['Utah', 'Ohio', 'Texas', 'Oregon'])
df
Out[363]:
In [364]:
s = df.ix[0]
s
Out[364]:
In [365]:
# 也是進行廣播
# 會將Series的索引批被盜DataFrame的columns, 然後沿著rows(軸0)的方向一直向下廣播
df + s
Out[365]:
In [366]:
# 如果索引不同,則索引會聯集之後自動對齊
df
Out[366]:
In [367]:
s2 = df['d']
s2
Out[367]:
In [368]:
# 如果希望索引自動匹配且在row方向上廣播,則必須用算術運算方法
# 傳入的軸就是希望匹配的軸
df.add(s2, axis = 0)
Out[368]:
NumPy的 ufuncs (元素級數組方法) 也可用於操作pandas物件
In [369]:
frame = DataFrame(np.random.randn(4, 3),
columns = list('bde'),
index = ['Utah', 'Ohio', 'Texas', 'Oregon'])
frame
Out[369]:
In [370]:
# NumPy的 ufuncs (元素級數組方法) 也可用於操作pandas物件
np.abs(frame)
Out[370]:
In [371]:
# DataFrame 上的 apply方法,可以實現元素級的運算
f = lambda x: x.max() - x.min()
frame.apply(f) # 預設會對每個 column操作
Out[371]:
In [372]:
# 沿著軸1
frame.apply(f, axis = 1)
Out[372]:
In [373]:
frame
Out[373]:
In [374]:
# 返回 由多個值組成的Series
def f(x):
return Series([x.min(), x.max()], index = ['min', 'max'])
frame.apply(f) # 會對每個column操作 f,每個column傳回一個Series,再重新組合成DataFrame
Out[374]:
In [375]:
# DataFrame 也可以透過 applymap(), 使用Python元素級的函式
f = lambda x: "{0:.3f}".format(x)
frame.applymap(f)
Out[375]:
In [376]:
# Series 也可以透過 map(), 使用Python元素級的函式
f = lambda x: "{0:.3f}".format(x)
f2 = frame['b']
f2.map(f)
Out[376]:
In [377]:
# 可以使用 sort_index方法 來對軸索引排序
obj = Series(range(4), index = list('dabc'))
obj
Out[377]:
In [378]:
# 可以使用 sort_index方法 來對軸索引排序
# 是針對索引來排序,而不是針對資料值
obj.sort_index()
Out[378]:
In [379]:
# DataFrame 也可以使用 sort_index 並指定軸來排序索引
frame = DataFrame(np.arange(8).reshape((2, 4)),
index = ['three', 'one'],
columns = list('dabc')
)
frame
Out[379]:
In [380]:
frame.sort_index(axis = 0)
Out[380]:
In [381]:
frame.sort_index(axis = 1)
Out[381]:
In [382]:
# 可以串接
frame.sort_index(axis = 0).sort_index(axis = 1)
Out[382]:
In [383]:
# 可以指定 降幕 排序
frame.sort_index(axis = 1, ascending = False)
Out[383]:
In [384]:
# 若要以值來排序,可以使用 sort_values()方法
obj['b'] = 4
print(obj)
obj.sort_values()
Out[384]:
In [385]:
# 若以sort_values()方法排序,空缺的值會被排到最後面
obj['a'] = None
print(obj)
obj.sort_values()
Out[385]:
In [386]:
# 要根據一個或多個column中的值來排序,可以使用 sort_values()
frame = DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame
Out[386]:
In [387]:
# 使用 sort_values() 根據值來排序
frame.sort_values('b')
Out[387]:
In [388]:
# 使用 sort_values() 根據多個columns的值來排序
frame.sort_values(['a', 'b'])
Out[388]:
In [389]:
df = DataFrame([[1.4, np.nan], [7.1, -4.5],
[np.nan, np.nan], [0.75, -1.3]],
index = list('abcd'),
columns = ['one', 'two'])
df
Out[389]:
In [390]:
# sum()傳回一個Series
df.sum()
Out[390]:
In [391]:
# 指定軸向做 sum()
df.sum(axis = 1)
Out[391]:
In [392]:
# NaN會被自動排除(當作0),可以使用skipna參數改變
df.sum(axis = 1, skipna = False)
Out[392]:
In [393]:
# idxmin, idxmax 傳回間接統計,最大值或最小值的索引
df.idxmin()
Out[393]:
In [394]:
df.idxmax()
Out[394]:
In [395]:
# 累積加總 cumsum()
df.cumsum()
Out[395]:
In [396]:
# describe 可以一次性產生多種統計數字
df.describe()
Out[396]:
In [397]:
# describe 對非數字資料,產生另外一種統計數字
obj = Series(list('aabc') * 4)
obj
Out[397]:
In [398]:
obj.describe()
Out[398]:
In [399]:
# 透過 參數對 計算出來的 彙總統計(如 相關係數和協方差)
import pandas.io.data as web
# from pandas_datareader import data, wb
all_data = {}
for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG']:
all_data[ticker] = web.get_data_yahoo(ticker, '1/1/2013', '1/1/2015')
price = DataFrame({tic: data['Adj Close'] for tic, data in all_data.items()})
volume = DataFrame({tic: data['Volume'] for tic, data in all_data.items()})
In [400]:
# 百分比變化
returns = price.pct_change()
returns.tail()
Out[400]:
In [401]:
# corr() 用來計算相關係數
returns.MSFT.corr(returns.IBM)
Out[401]:
In [402]:
# cov()用來計算協方差
returns.MSFT.cov(returns.IBM)
Out[402]:
In [403]:
# DataFrame的 corr(), cov() 將會返回相同形狀的矩陣
returns.corr()
Out[403]:
In [404]:
returns.cov()
Out[404]:
In [405]:
# 利用DataFrame的 corrwith()方法,可以計算列或行 跟另外一個Series或DataFrame之間的相關係數
returns.corrwith(returns.IBM)
Out[405]:
In [406]:
returns.corrwith(volume)
Out[406]:
In [407]:
obj = Series(list('cadaabbcc'))
obj
Out[407]:
In [408]:
# uniquie 唯一值
obj.unique()
Out[408]:
In [409]:
# 排序之後的唯一值
np.sort(obj.unique())
Out[409]:
In [410]:
# value_count()傳回 各值出現的次數,依照出現的次數降幕排序
obj.value_counts()
Out[410]:
In [411]:
# value_counts()可以做為頂層函式,依照出現的次數降幕排序
pd.value_counts(obj)
Out[411]:
In [412]:
# 可以使用 sort 參數 禁止排序
pd.value_counts(obj, sort = False)
Out[412]:
In [413]:
# 用 isin() 判斷成員資格
mask = obj.isin(['b', 'c'])
In [414]:
mask
Out[414]:
In [415]:
# 以NaN標示缺失數據
s = Series(['aardradf', 'asdfasfas', np.nan, 'asdfasfasf'])
s
Out[415]:
In [416]:
# 用 isnull()來檢驗NaN
s.isnull()
Out[416]:
In [417]:
# None等同於 NaN
s[0] = None
s.isnull()
Out[417]:
In [418]:
from numpy import nan as NA
data = Series([1, NA, 3.5, NA, 7])
data
Out[418]:
In [419]:
# 用 dropna()捨棄 NA,index 並不會重新設定
data.dropna()
Out[419]:
In [420]:
# 也可透過 boolean型索引過濾
data[data.notnull()]
Out[420]:
In [421]:
# 對 DataFrame來說,dropna()預設捨棄任何有NA的row
df = DataFrame([[1., 6.5, 3.], [1., NA, NA], [NA, NA, NA],[NA, 6.5, 3.]])
df
Out[421]:
In [422]:
# dropna()預設捨棄任何有NA的row
df.dropna()
Out[422]:
In [423]:
# 若傳入 how='all',則只捨棄 所有數值皆為NA的那個row
df.dropna(how='all')
Out[423]:
In [424]:
# 要用這種方式捨棄column,則需傳入 axis=1即可
df[3] = NA
df
Out[424]:
In [425]:
# 傳入 axis=1,捨棄整列為NA的column
df.dropna(axis = 1, how = 'all')
Out[425]:
In [426]:
# 使用 thresh 參數,只留下一部分觀測數據
df = DataFrame(np.random.randn(7, 3))
df
Out[426]:
In [427]:
df.ix[:4, 1] = NA
df.ix[:2, 2] = NA
df
Out[427]:
In [428]:
# 用 thresh 參數
df.dropna(thresh = 3)
Out[428]:
In [429]:
# 使用 fillna()來填充缺失數據
df.fillna(0)
Out[429]:
In [430]:
# 依據字典,對不同的column填充不同的值
df.fillna({1: 0.5, 2: -1})
Out[430]:
In [431]:
# fillna()預設傳回副本,但也可以用 inplace 參數來就地修改
df.fillna(0, inplace = True)
df
Out[431]:
In [432]:
# 差值的方法 ffill, bfill
df = DataFrame(np.random.randn(6, 3))
df.ix[2:, 1] = NA
df.ix[4:, 2] = NA
df
Out[432]:
In [433]:
# 'ffill'的插值方式
df.fillna(method = 'ffill')
Out[433]:
In [434]:
# 限制插值的次數
df.fillna(method = 'ffill', limit = 2)
Out[434]:
In [435]:
# 用 mean 作為插入值
df.fillna(df.mean())
Out[435]:
In [436]:
# 使用 MultiIndex 索引的Series的格式化輸出形式
# 可以用一維的方式來表達二維的資料,以低維度的形式來處理高維度的資料
s = Series(np.random.randn(10),
index = [list('aaabbbccdd'), [1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
s
Out[436]:
In [437]:
s.index
Out[437]:
In [438]:
# 選取數據 子集合
s['b']
Out[438]:
In [439]:
s['b':'c']
Out[439]:
In [440]:
s.ix[['b', 'c']]
Out[440]:
In [441]:
# 選取 內層 的數據
s[:, 2]
Out[441]:
In [442]:
# 數據可以透過 unstack 方法被重新安排到一個 DataFrame中
s.unstack()
Out[442]:
In [443]:
# unstack 的逆運算是 stack
s.unstack().stack()
Out[443]:
In [444]:
# 對於一個 DataFrame,每條軸都可以有分層索引
df = DataFrame(np.arange(12).reshape((4, 3)),
index = [['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
columns = [['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']])
df
Out[444]:
In [445]:
# 每層的索引都可以有名字
df.index.names = ['key1', 'key2']
df.columns.names = ['state', 'color']
df
Out[445]:
In [446]:
# 可以藉由索引來選取列分組
df['Colorado']
Out[446]:
In [447]:
# 可以先建構好 MultiIndex 物件,再用來創建 DataFrame物件
mi = pd.MultiIndex.from_arrays([['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']], names = ['state', 'color'])
mi
Out[447]:
In [448]:
# 用 swaplevel 互換級別
df.swaplevel('key1', 'key2')
Out[448]:
In [449]:
# sortlevel 根據單一個級別中的值對數據進行排序
df.swaplevel('key1', 'key2').sortlevel(0)
Out[449]:
In [450]:
df.swaplevel('key1', 'key2').sortlevel(1)
Out[450]:
In [451]:
# 設定 level 參數,用來指定對某個索引級別來操作統計函式
df.sum(level = 'key2')
Out[451]:
In [452]:
# 對column上的索引級別來操作統計函式
df.sum(axis = 1, level = 'color')
Out[452]:
In [453]:
# 將 DataFrame的一個或多個列當作行索引來用,或者希望將行索引變成DataFrame的列
df = DataFrame({'a': range(7), 'b': range(7, 0, -1),
'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'],
'd': [0, 1, 2, 0, 1, 2, 3]})
df
Out[453]:
In [454]:
# set_index() 會將其一個或多個columns轉換為 row索引,並創建一個 DataFrame
df2 = df.set_index(['c', 'd'])
df2
Out[454]:
In [455]:
# 預設情況下,這些columns會被移除,但也可以設定 drop參數將之保留下來
df2 = df.set_index(['c', 'd'], drop = False)
df2
Out[455]:
In [456]:
# reset_index() 會將 row方向上的多層次索引 移動到 column上
df2 = df.set_index(['c', 'd'])
df2
Out[456]:
In [457]:
# reset_index() 會將 row方向上的多層次索引 移動到 column上
df2.reset_index()
Out[457]: